package utwente.hmi.touchmol;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.util.LinkedList;
import java.util.ListIterator;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.border.Border;

import utwente.hmi.touchmol.elements.*;

import com.merl.diamondtouch.DtlibInputTframe;

/**
 * @author Jeroen Logtenberg
 */
public class ExplicitGUI extends TouchMolGUI {

	private static final long serialVersionUID = 1L;

	public static final int LOCATION_TURNPANEL = 7004;
	
	private LinkedList<TurnPanel> panels;
	
	private long[] lastTurnChange = new long[5];
	
	public ExplicitGUI(){
		super();
		
		lastTurnChange[0] = 0;
		lastTurnChange[1] = 0;
		lastTurnChange[2] = 0;
		lastTurnChange[3] = 0;
		lastTurnChange[4] = 0;
	}
	
	@Override
	/**
	 * The explicit GUI has turn buttons on the left, right and bottom of the screen, 
	 * as well as the standard molecule and bookmark panels.
	 */
	void makeLayout() {
		
		SCALE = 5;
		
		int molpanelSize = (displayWidth / SCALE * (SCALE - 2)) + (displayWidth / SCALE) - 150;
		
		jmolView = new MolPanel(molpanelSize,displayHeight - 75);

		screens = new ScreenshotPanel((displayWidth / SCALE) - 2, displayHeight - 75);
		
		//turnpanels.
		panels = new LinkedList<TurnPanel>();
		TurnPanel blue = new TurnPanel(73, displayHeight - 75, UserButton.getBlueButton());
		TurnPanel red = new TurnPanel(displayWidth / 2 - 2, 73, UserButton.getRedButton());
		TurnPanel green = new TurnPanel(displayWidth / 2 - 2, 73, UserButton.getGreenButton());
		TurnPanel yellow = new TurnPanel(73, displayHeight - 75 , UserButton.getYellowButton());
		panels.add(blue); panels.add(red); panels.add(green); panels.add(yellow);
		
		getContentPane().setLayout(new BorderLayout(1,1));
		
		getContentPane().add(blue, BorderLayout.WEST);
		JPanel bottompanel = new JPanel();
		bottompanel.setLayout(new BorderLayout());
		bottompanel.add(red, BorderLayout.WEST);
		bottompanel.add(green, BorderLayout.EAST);
		getContentPane().add(bottompanel, BorderLayout.SOUTH);
		getContentPane().add(yellow,BorderLayout.EAST);
		
		JPanel centerpanel = new JPanel();
		centerpanel.setLayout(new BorderLayout(1,1));
		centerpanel.add(jmolView, BorderLayout.CENTER);
		centerpanel.add(screens, BorderLayout.EAST);
		getContentPane().add(centerpanel);
		
		Border line = BorderFactory.createLineBorder(Color.white, 5);
		screens.setBorder(line);
		screens.setIgnoreRepaint(true);
		
	}

	@Override
	/**
	 * Determines if the user touched the molpanel, screenshot panel or one of the turn panels.
	 * In the case of a turn panel, the input location is passed on to process.
	 */
	int determineLocation(int userID, DtlibInputTframe dtInputFrame) {
		
		debug("Input frame size: " + touchRect(dtInputFrame));
		Point center = calculateCenter(touchRect(dtInputFrame));
		
		if(jmolView.panelTouched(center))
			return LOCATION_MOLPANEL;
		else if(screens.panelTouched(center))
			return LOCATION_SCREENSHOTPANEL;
		else{
			ListIterator<TurnPanel> it = panels.listIterator();
			TurnPanel p;
			//TouchMolGUI.debug("Checking for touch on " + location);
			while(it.hasNext()){
				p = it.next();
				if(p.panelTouched(center)){
					handleRequest(userID, center, p);
					return LOCATION_TURNPANEL;
				}
			}
			return -1;
		}
	}
	
	/**
	 * Determines what action to take when a turn panel is touched.
	 * @param userID Only the user the turn panel belongs to can activate the button.
	 * @param center The center of the touch.
	 * @param panel The turn panel in question.
	 */
	private void handleRequest(int userID, Point center, TurnPanel panel){
		long current = System.currentTimeMillis();
		long timeDiff = current - lastTurnChange[userID];
		long threshold = 500L; //Time threshold between turn actions in milliseconds.
		
		UserButton res = panel.buttonTouched(center);
		
		if(res != null && res.getUserID() == userID && timeDiff > threshold){
			if(currentTurn == userID){
				releaseTurn(res);
				panel.releaseTurn(res);
				TouchMolGUI.debug("Releasing turn.");
			} else if(currentTurn == -1){
				panel.takeTurn(res);
				takeTurn(res);
				TouchMolGUI.debug("Taking turn.");
			} else{
				panel.requestTurn(res);
				TouchMolGUI.debug("Requesting turn.");
			}
			lastTurnChange[userID] = current;
		} else{
			TouchMolGUI.debug("Wrong user touched panel.");
		}
		
	}

	@Override
	public void releaseTurn(UserButton user) {
		ListIterator<TurnPanel> it = panels.listIterator();
		TurnPanel p;
		while(it.hasNext()){
			p = it.next();
			if(p.getUser() == user.getUserID())
				p.releaseTurn(user);
		}
		currentTurn = -1;
		
	}

	@Override
	public void requestTurn(UserButton user) {
		//No requesting possible.
		
	}

	@Override
	public void takeTurn(UserButton user) {
		currentTurn = user.getUserID();
	}
}
